﻿using System;
using System.Diagnostics;
using Outlook = Microsoft.Office.Interop.Outlook;
using System.Data.SqlServerCe;
using Office = Microsoft.Office.Core;
using System.Threading;

namespace Investafinance.Sync.Shell
{
    /// <summary>
    /// Обалочка для папки outlook здесь перехватываются все необходимые события
    /// </summary>
    public class ShellFolderSync<TItemType> where TItemType : class
    {
        // строка конекта к бызе данных
        private string scon;

        //Название таблиц
        private string nameTable;
       // private string nameTableMeta;
        private string nameFolder;

        public string NameFolder
        {
            get 
            {
                return nameFolder; 
            }
        }

        private  Outlook.OlDefaultFolders tTypeFolder;
        public static Outlook.Application localApplication = null;

        //Ccылка на обьект Selection для того чтобы хранить делигаты
        public Outlook.Selection Selection;

        //Ссылка на MAPIпапку 
        public  Outlook.MAPIFolder MapiFolder = null;

        //Для хранения делигата на перемещение записи в папку удалённые 
        private Outlook.Folder Folder;
        private Outlook.Items FolderItems;
        private Outlook.Explorer _explorer;

        //Ссылка на папку с задачами это стандартная папка (корень на колекцию папок вложеных  в задачами)
        //нужна для того чтобыхранить делегат на удаление папки
        public Outlook.Folders ContactFolders = null;

        //Название полей и Соотвецтвующие им Ассоциации в Outlook
        public string[,] associateMap = null;

        //Уникальные идентификаторы папки в Outlook
        private string m_FolderStoreID = "";
        private string m_FolderEntryID = "";
        //Обьект Inspectors
        private Outlook.Inspectors m_Inspectors;
        private string m_messageClass;
        private string m_Url;
        private string m_ListName;
        private UserControls.PageUrl controlURL;


        //обьект сесии
        private Outlook.NameSpace current_NameSpace;
        private Credential m_Credential;
        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="scon">Строка конекта к БД</param>
        /// <param name="nameTable">Название синхронизируемой таблици (должно совподать с названием листа SharePoint)</param>
        /// <param name="nameFolder">Название папки Outlook</param>
        /// <param name="tTypeFolderVar">Тип корневой папки Outlook</param>
        /// <param name="associateMapField">Моссив названий синхронезируемых полей 
        /// (Смещение = 0 SHAREPOINT НАИМЕНОВАНИЕ поля,
        ///  Смещение = 1 OUTLOOK НАИМЕНОВАНИЕ поля,
        ///  Смещение = 2 (если 1 ==UserProperties[..] (.. - цифра или строка)) то наименование Столбца в outlook которое будет создаваться, 
        ///  Смещение = 3 (если 1 ==UserProperties[..] (.. - цифра или строка)) то тип столбца )</param>
        /// <param name="localApplicationVar">Указатель на Outlook.Application </param>
        /// <param name="messageClass">Название класса сообщений</param>
        public ShellFolderSync(string scon, string nameTable,
                               string nameFolder, Outlook.OlDefaultFolders tTypeFolderVar,
                               string[,] associateMapField, Outlook.Application localApplicationVar, string messageClass, string url, string ListName, ref Credential credential)
        {
            Debug.Assert(scon != null, "ShellFolderSync.cs конструктор scon != null");
            Debug.Assert(scon != "", "ShellFolderSync.cs конструктор scon != ''");

            Debug.Assert(nameFolder != null, "ShellFolderSync.cs конструктор nameFolder != null");
            Debug.Assert(nameFolder != "", "ShellFolderSync.cs конструктор nameFolder != ''");

            Debug.Assert(nameTable != null, "ShellFolderSync.cs конструктор nameTable != null");
            Debug.Assert(nameTable != "", "ShellFolderSync.cs конструктор nameTable != ''");

            Debug.Assert(associateMapField != null, "ShellFolderSync.cs конструктор associateMapField != null");
            Debug.Assert(localApplicationVar != null, "ShellFolderSync.cs конструктор localApplicationVar != null");

            m_Credential = credential;
            m_ListName = ListName;
            m_Url = url;

            this.tTypeFolder = tTypeFolderVar;
            associateMap = associateMapField;
            this.scon = scon;
            this.nameTable = nameTable;
            this.nameFolder = nameFolder;
            //this.nameTableMeta = nameTableMeta;
            localApplication = localApplicationVar;
            m_explorer = localApplication.ActiveExplorer();
            m_messageClass = messageClass;

            m_Inspectors = localApplicationVar.Inspectors;
            m_Inspectors.NewInspector += new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);

            //установим указатель на текущею сесию outlook
            current_NameSpace = localApplicationVar.Session;
            localApplication.FolderContextMenuDisplay += new Microsoft.Office.Interop.Outlook.ApplicationEvents_11_FolderContextMenuDisplayEventHandler(VievContexMenu);
            //прикрепим указатель на добавление закладки в настройках папки
            current_NameSpace.OptionsPagesAdd += new Microsoft.Office.Interop.Outlook.NameSpaceEvents_OptionsPagesAddEventHandler(PagesAdd);


            //_explorer = localApplication.ActiveExplorer();
            //_explorer.BeforeItemPaste += new Outlook.ExplorerEvents_10_BeforeItemPasteEventHandler(EventBeforeItemPaste);


            if (ShearchFolder(tTypeFolder))
            {
                Debug.Assert(MapiFolder != null, "ShellFolderSync.cs конструктор MapiFolder != null");
                Folder = ((Outlook.Folder)MapiFolder);
                Folder.BeforeItemMove += new Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(RemoveCollaboratore);
                FolderItems = Folder.Items;
                //FolderItems.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(EventItemAdd);
            }
        }


        //событие при добавлении в папку  записей 
        //  при синхронизиции и ручном добавлении не обрабатывать
        //  расчитан на Вставку Перемещение из других папок
        //  Поэтому обробатывать только если возникло событие 
        private void EventBeforeItemPaste(ref object ClipboardContent, Outlook.MAPIFolder Target, ref bool Cancel)
        {
            if (Target.StoreID == MapiFolder.StoreID)
                if (Target.EntryID == MapiFolder.EntryID)
            {
                flagItemPasteCurrentFolder = true;
            }
            else
                flagItemPasteCurrentFolder = false; 
        }
        bool flagItemPasteCurrentFolder=false; 

        //событие при добавлении в папку  записей 
        //  при синхронизиции и ручном добавлении не обрабатывать
        //  расчитан на Вставку Перемещение из других папок
        //  Поэтому обробатывать только если возникло событие 
        private void EventItemAdd(object Item)
        {
            if (flagItemPasteCurrentFolder)
            {
                SqlCeConnection conn = new SqlCeConnection(scon);
                try
                {
                    //открываем подключение 
                    conn.Open();

                    Shell.ShellFieldItem<TItemType> getFields = new ShellFieldItem<TItemType>((TItemType)Item, associateMap);
                    //пройдёмся по полям которые нам нужны узнаем их значения, потом запишем в БД

                    string sName = "(";
                    string sValue = "(";

                    for (int i = 0; i < Convert.ToInt32(associateMap.Length / 4); i++)
                    {
                        bool isIn = false;
                        for (int j = 0; j < i - 1; j++)
                        {
                            if (associateMap[j, 0] == associateMap[i, 0])
                            {
                                isIn = true;
                                break;
                            }
                        }

                        if(!isIn)
                        if (associateMap[i, 0] != "owshiddenversion")
                            if (associateMap[i, 0] != "ID")
                            {
                                sName += associateMap[i, 0] + ",";
                                sValue += "'" + getFields[associateMap[i, 1]] + "',";
                            }
                    }
                    sName += "Modify,EntryIDInOutlook,ID,owshiddenversion)";
                    sValue += "'I','" + getFields["EntryID"] + "','" + getFields["EntryID"] + "','1')";

                    string MyEntryID = DateTime.Now.ToString() + "::" + DateTime.Now.Millisecond.ToString() + " $,$ " + localApplication.GetNamespace("MAPI").CurrentUser.Name; 
                    //Установим факт
                    getFields["Mileage", "Mileage"] = MyEntryID;
                    
                    string s = "INSERT INTO Sync_" + nameTable + " " + sName + " VALUES " + sValue;
                    SqlCeCommand cmd = new SqlCeCommand(s, conn);
                    cmd.ExecuteNonQuery();
                    Outlook.ContactItem ci = ((Outlook.ContactItem)Item);
                    ci.MessageClass = "IPM.Contact.Collaboratore";
                    ci.Save();
                    System.Windows.Forms.MessageBox.Show(ci.MessageClass);
                }
                catch(Exception errs)
                {
                    Debug.Assert(false, "ShellFolderSync.cs EventItemAdd()" + errs.Message + " -->" + errs.Source); 
                }
            }
        }


        private Office.CommandBarButton MyButtonSync;
        private void VievContexMenu(Office.CommandBar CommandBar, Outlook.MAPIFolder Folder)
        {
            if (this.Folder.StoreID == Folder.StoreID)
                if (this.Folder.EntryID == Folder.EntryID)
            {
                MyButtonSync = (Office.CommandBarButton)CommandBar.Controls.Add(1, 1, "", 1, true);
                MyButtonSync.Visible = true;
                MyButtonSync.Caption = "Synchronize";
                MyButtonSync.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(ContextMenuClick);
                MyButtonSync.Style = Office.MsoButtonStyle.msoButtonIconAndCaption;
                // add an icon to the button
                System.Drawing.Image imgStreamPic;
                stdole.IPictureDisp oPic = null;
                MyAxHost ax = new MyAxHost();
                imgStreamPic = Investafinance.Properties.Resources.favicon.ToBitmap();
                oPic = ax.IPictureDispFromImage(imgStreamPic);
                MyButtonSync.Picture = oPic;
            }
        }

        private void ContextMenuClick(Office.CommandBarButton Ctrl, ref bool CancelDefault)
        {
         
            if (this.ShearchFolderORAdd())
            {
                localApplication.ActiveExplorer().SelectFolder(this.MapiFolder);
                Thread potokSync = new Thread(Sync);
                potokSync.Start();
            }
        }

        private bool flagEndSync = true;
        public void Sync()
        {
            if (flagEndSync)
            {
                flagEndSync = false;
                ShellFieldItem<TItemType> oItem = new ShellFieldItem<TItemType>(scon, this.m_ListName, null, this.associateMap);
                ShellSynchronizer<TItemType> s = new ShellSynchronizer<TItemType>(this.m_ListName, this.nameFolder, scon, oItem);
                s.InitializeSync(this, this.m_ListName, m_Credential);
                flagEndSync = true;
            }
        }

        private void PagesAdd(Outlook.PropertyPages Pages, Outlook.MAPIFolder Folder)
        {
            if (this.Folder != null)
            {
                if (this.Folder.StoreID == Folder.StoreID)
                    if (this.Folder.EntryID == Folder.EntryID)
                {
                    Pages.Add(controlURL, "Investa Finance");  
                }
            }
        }

        private void changeMasageClass(object sender, UserControls.PageUrl.ChangeMessageClassEventArgs  e)
        {
            m_messageClass = e.MassageClass;
        }

        //Событие при добавлении нового Item (из другой папки)
        private void ItemAdd(object Item)
        {
           // ((Outlook.AddressList)localApplication.GetNamespace().MAPIOBJECT).
            Outlook.ContactItem ci = ((Outlook.ContactItem)Item);
            string s = ci.EntryID;
            if (ci.Parent is Outlook.MAPIFolder)
            {
                System.Windows.Forms.MessageBox.Show(((Outlook.MAPIFolder)ci.Parent).FolderPath);
            }
        }


        Outlook.Explorer m_explorer;
        private void Inspectors_NewInspector(Outlook.Inspector Inspector)
        {       
            if(MapiFolder != null)
                if ((m_explorer.CurrentFolder.EntryID == m_FolderEntryID) && (m_explorer.CurrentFolder.StoreID == m_FolderStoreID))
            {
                if (Inspector.CurrentItem is Outlook.ContactItem)
                {
                    if (((Outlook.ContactItem)Inspector.CurrentItem).Parent is Outlook.MAPIFolder)
                    {
                        ((Outlook.ContactItem)Inspector.CurrentItem).MessageClass = m_messageClass;
                    }
                }
            }
        }



        //диструктор
        ~ShellFolderSync()
        {
            //m_Inspectors.NewInspector -= new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);
        }

        #region Поиск ссылка на папку синхронезированые с шарапоинтам
        public bool ShearchFolder(Outlook.OlDefaultFolders tTypeFolder)
        {
            bool b = true;

            //для начала надо проверить создавать или уже создана папка (если есть запись в таблице Folders то создавать ненадо)
            SqlCeConnection conn = new SqlCeConnection(scon);
            try
            {
                //открываем подключение 
                conn.Open();
                //инициализируем Command 
                SqlCeCommand cmd = new SqlCeCommand("select EntryID,StoreID,MessageClass from Folders where Name='" + nameFolder + "' ", conn);

                //выполняем селект
                SqlCeDataReader dr = cmd.ExecuteReader(System.Data.CommandBehavior.SingleRow);
                cmd.Dispose();
                cmd = null;

                //если да то читаем значения и получаем указатель на папку с вакансиями
                if (dr.Read())
                {
                    MapiFolder = localApplication.Session.GetFolderFromID(dr["EntryID"].ToString(), "");

                    //Получим указатель на папку с задачами
                    Outlook.MAPIFolder DefaultFolder = localApplication.Session.GetDefaultFolder(tTypeFolder);

                    if (ContactFolders == null)
                    {
                        Debug.Assert(DefaultFolder != null, "ShellFolderSync.cs ShearchFolder() DefaultFolder !=null");
                        //получим указатель на коллекцию Folders
                        ContactFolders = DefaultFolder.Folders;
                        //Прикрепим делигат на удаление папки (чтобы отслеживать удаление папки с вакансиями)
                        ContactFolders.FolderRemove += new Outlook.FoldersEvents_FolderRemoveEventHandler(FolderRamuve);
                        
                    }
                    this.m_FolderEntryID = dr["EntryID"].ToString();
                    this.m_FolderStoreID = dr["StoreID"].ToString();
                    this.m_messageClass = dr["MessageClass"].ToString();
                    controlURL = new UserControls.PageUrl(m_FolderEntryID, scon);
                    controlURL.EventChangeMassageClass += changeMasageClass;
                    b = true;
                }
                else
                {
                    b = false;
                }
                dr.Close();
            }
            catch (Exception err)
            {
                b = false;
                Debug.Assert(false, "ShellFolderSync.cs ShearchFolder()"  + err.Message + "-->" + err.Source); 
            }
            finally
            {
                //закрываем подключение
                conn.Close();
                conn.Dispose();
                conn = null;
            }
            return b;
        }
        #endregion

        #region Поиск ссылка на папку синхронезированые с шарапоинтам (если нет папки то дабавить)
        public bool ShearchFolderORAdd()
        {
           return ShearchFolderORAdd(this.tTypeFolder);
        }

        public bool ShearchFolderORAdd(Outlook.OlDefaultFolders tTypeFolder)
        {
            bool b = true;

            //для начала надо проверить создавать или уже создана папка (если есть запись в таблице Folders то создавать ненадо)
            SqlCeConnection conn = new SqlCeConnection(scon);
            try
            {
                //открываем подключение 
                conn.Open();
                //инициализируем Command 
                SqlCeCommand cmd = new SqlCeCommand("select EntryID,StoreID,MessageClass from Folders where Name='" + nameFolder + "' ", conn);

                //выполняем селект
                SqlCeDataReader dr = cmd.ExecuteReader(System.Data.CommandBehavior.SingleRow);
                cmd.Dispose();
                cmd = null;

                //если да то читаем значения и получаем указатель на папку с вакансиями
                if (dr.Read())
                {
                    MapiFolder = localApplication.Session.GetFolderFromID(dr["EntryID"].ToString(), "");

                    //Получим указатель на папку с задачами
                    Outlook.MAPIFolder DefaultFolder = localApplication.Session.GetDefaultFolder(tTypeFolder);

                    if (ContactFolders == null)
                    {
                        Debug.Assert(DefaultFolder != null, "ShellFolderSync.cs ShearchFolderORAdd() DefaultFolder !=null"); 
                        //получим указатель на коллекцию Folders
                        ContactFolders = DefaultFolder.Folders;
                        //Прикрепим делигат на удаление папки (чтобы отслеживать удаление папки с вакансиями)
                        ContactFolders.FolderRemove += new Outlook.FoldersEvents_FolderRemoveEventHandler(FolderRamuve);
                    }
                    this.m_FolderEntryID = dr["EntryID"].ToString();
                    this.m_FolderStoreID = dr["StoreID"].ToString();
                    this.m_messageClass = dr["MessageClass"].ToString();
                    controlURL = new UserControls.PageUrl(m_FolderEntryID, scon);
                    controlURL.EventChangeMassageClass += changeMasageClass;
                }
                else
                {
                    //для начала создадим папку
                    //Получим указатель на папку с задачами
                    Outlook.MAPIFolder TaskFolder = localApplication.Session.GetDefaultFolder(tTypeFolder);
                    //получим указатель на коллекцию Folders
                    ContactFolders = TaskFolder.Folders;
                    //Прикрепим делигат на удаление папки (чтобы отслеживать удаление папки с вакансиями)
                    ContactFolders.FolderRemove += new Outlook.FoldersEvents_FolderRemoveEventHandler(FolderRamuve);
                    

                    //Возмём коллекцию Folders для того чтоб добавить сваю папку
                    MapiFolder = TaskFolder.Folders.Add(nameFolder, tTypeFolder);
                    Folder = ((Outlook.Folder)MapiFolder);

                    Folder.BeforeItemMove += new Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(RemoveCollaboratore);
                    
                    
                    //CollaboratoreFolder.DefaultMessageClass = "";
                    //запишем в таблицу запись о том что у нас уже создана папка Vacancy
                    /* INSERT INTO dbf_name [(fname1 [, fname2, ...])]
                          VALUES (eExpression1 [, eExpression2, ...])*/
                    cmd = new SqlCeCommand("INSERT INTO Folders (Name,EntryID,StoreID,Url,MessageClass,ListName) " +
                                                      "VALUES ('" + nameFolder + "','" + MapiFolder.EntryID
                                                      + "','" + MapiFolder.StoreID + "','" + m_Url + "','" + m_messageClass + "','"+m_ListName+"')", conn);
                    this.m_FolderEntryID = MapiFolder.EntryID;
                    this.m_FolderStoreID = MapiFolder.StoreID;
                    controlURL = new UserControls.PageUrl(m_FolderEntryID, scon);
                    controlURL.EventChangeMassageClass += changeMasageClass;

                    //выполняем команду 
                    cmd.ExecuteNonQuery();
                    cmd.Dispose();
                    cmd = null;
                    
                    //добавим поля которые нам нужны UserProperties (если такие есть)
                    string[,] data = associateMap;//ShellFolderSync<TItemType>.associateMap;
                    if (data != null)
                    {
                        for (int i = 0; i < Convert.ToInt32(data.Length / 4); i++)
                        {
                            if (data[i, 1].IndexOf("UserProperties") != -1)
                            {
                                Outlook.OlUserPropertyType up;
                                
                                switch (data[i, 3])
                                {
                                    case "olOutlookInternal":
                                        up = Outlook.OlUserPropertyType.olCombination;
                                        break;
                                    case "olCurrency":
                                        up = Outlook.OlUserPropertyType.olCurrency;
                                        break;
                                    case "olDateTime":
                                        up = Outlook.OlUserPropertyType.olDateTime;
                                        break;
                                    case "olDuration":
                                        up = Outlook.OlUserPropertyType.olDuration;
                                        break;
                                    case "olEnumeration":
                                        up = Outlook.OlUserPropertyType.olEnumeration;
                                        break;
                                    case "olFormula":
                                        up = Outlook.OlUserPropertyType.olFormula;
                                        break;
                                    case "olInteger":
                                        up = Outlook.OlUserPropertyType.olInteger;
                                        break;
                                    case "olNumber":
                                        up = Outlook.OlUserPropertyType.olNumber;
                                        break;
                                    case "olPercent":
                                        up = Outlook.OlUserPropertyType.olPercent;
                                        break;
                                    case "olSmartFrom":
                                        up = Outlook.OlUserPropertyType.olSmartFrom;
                                        break;
                                    case "olText":
                                        up = Outlook.OlUserPropertyType.olText;
                                        break;
                                    case "olYesNo":
                                        up = Outlook.OlUserPropertyType.olYesNo;
                                        break;
                                    default:
                                        up = Outlook.OlUserPropertyType.olText;
                                        break;
                                }

                                MapiFolder.UserDefinedProperties.Add(data[i, 2], up, 1, null);
                            }
                        }
                    }
                }
                dr.Close();
            }
            catch (Exception err)
            {
                b = false;

                if (err.Message.IndexOf("Не удается открыть элемент. Попробуйте еще раз.") != -1)
                {
                    try
                    {
                        //инициализируем Command 
                        //удалим все вакансии
                        SqlCeCommand cmd;
                        //может упасть в екзепшен в случае если не разу не синхронизировались а папку уже удалили
                        try
                        {
                            //удалим таблицу синхранизированную
                            cmd = new SqlCeCommand("DROP TABLE Sync_" + nameTable + ";", conn);
                            cmd.ExecuteNonQuery();
                            //удалим запись  о последней синхранизации
                            cmd = new SqlCeCommand("delete from Sync where TableName  in (MetaData_'" + nameTable + "')", conn);
                            cmd.ExecuteNonQuery();
                            cmd.Dispose();
                            cmd = null;
                        }
                        catch (Exception)
                        {
                            cmd = null;
                        }
                        //Удалим запись о существовании папки
                        cmd = new SqlCeCommand("DELETE FROM  Folders where Name in ('" + nameFolder + "') ", conn);
                        //выполняем команду этот оператор значит выполнить отличную от Select
                        cmd.ExecuteNonQuery();
                        cmd.Dispose();
                        cmd = null;
                    }
                    catch (Exception errs)
                    {
                        Debug.Assert(false, "ShellFolderSync.cs ShearchFolderORAdd()" + errs.Message + " -->" + errs.Source); 
                    }
                }
                else
                    Debug.Assert(false, "ShellFolderSync.cs ShearchFolderORAdd()" + err.Message + "-->" + err.Source); 
            }
            finally
            {
                //закрываем подключение
                conn.Close();
                conn.Dispose();
                conn = null;
            }
            return b;
        }
        #endregion

        #region при удалении папки
        private void FolderRamuve()
        {
            //Outlook.FoldersClass fol;
            //fol.
            if (Folder!=null)
                Folder.BeforeItemMove -= new Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(RemoveCollaboratore);
            if (ContactFolders != null)
                ContactFolders.FolderRemove -= new Outlook.FoldersEvents_FolderRemoveEventHandler(FolderRamuve);
            //если папка с вакансиями переместилась в в папку Удалённые то мы её удалили надо отчистить все таблици
            if (MapiFolder != null)

                if ((MapiFolder.FolderPath.IndexOf("Удаленные") != -1)
                    ||
                    //итальянский вариант
                    (MapiFolder.FolderPath.IndexOf("Posta eliminata") != -1)  )
                {
                    SqlCeConnection conn = new SqlCeConnection(scon);
                    try
                    {
                        //открываем подключение 
                        conn.Open();
                        //инициализируем Command 
                        //удалим все вакансии
                        SqlCeCommand cmd;
                        //может упасть в екзепшен в случае если не разу не синхронизировались а папку уже удалили
                        try
                        {
                            //удалим таблицу синхранизированную
                            cmd = new SqlCeCommand("DROP TABLE Sync_" + nameTable + ";", conn);
                            cmd.ExecuteNonQuery();
                        }
                        catch (Exception)
                        {
                            cmd = null;
                        }

                        try
                        {
                            //удалим таблицу синхранизированную
                            cmd = new SqlCeCommand("DROP TABLE MetaData_" + nameTable + ";", conn);
                            cmd.ExecuteNonQuery();
                        }
                        catch (Exception)
                        {
                            cmd = null;
                        }

                        try
                        {
                            //удалим запись  о последней синхранизации
                            cmd = new SqlCeCommand("delete from Sync where TableName  in ('MetaData_" + nameTable + "');", conn);
                            cmd.ExecuteNonQuery();
                            //подаждём пока поток завершит свою работу
                            cmd.Dispose();
                            cmd = null;
                            // да-бы удаляя ещё раз из этой колекции папок  другие папки не попасть в расплох
                            MapiFolder = null;

                        }
                        catch (Exception)
                        {
                            cmd = null;
                        }
                        //Удалим запись о существовании папки
                        cmd = new SqlCeCommand("DELETE FROM  Folders where Name in ('" + nameFolder + "') ", conn);
                        //выполняем команду этот оператор значит выполнить отличную от Select
                        cmd.ExecuteNonQuery();
                        cmd.Dispose();
                        cmd = null;
                        
                        //стираем указатели
                        m_FolderStoreID = "";
                        m_FolderEntryID = "";

                        controlURL.EventChangeMassageClass -= changeMasageClass;
                        controlURL.Dispose();
                    }
                    catch (Exception err)
                    {
                        Debug.Assert(false, "ShellFolderSync.cs FolderRamuve()" + "" + err.Message + "-->" + err.Source ); 
                    }
                    finally
                    {
                        //закрываем подключение
                        conn.Close();
                        conn.Dispose();
                        conn = null;
                    }
            }
        }
        #endregion

        #region при удалении Item в папке
        private void RemoveCollaboratore(object Item, Outlook.MAPIFolder MoveTo, ref bool Cancel)
        {

            SqlCeConnection conn = new SqlCeConnection(scon);
            try
            {
                string ID = "";
                if (Item is Outlook.TaskItem)
                {
                    ID = ((Outlook.TaskItem)Item).Mileage;
                }
                else
                if (Item is Outlook.ContactItem)
                {
                    ID = ((Outlook.ContactItem)Item).Mileage;
                }
                else
                if (Item is Outlook.PostItem)
                {
                    ID = ((Outlook.PostItem)Item).Mileage;
                }   

                //открываем подключение 
                conn.Open();
                //инициализируем Command 
                Selection = localApplication.ActiveExplorer().Selection;

                SqlCeCommand cmd = new SqlCeCommand("select Modify,owshiddenversion from Sync_" + nameTable +
                  " where ID IN ('" + ID + "') ", conn);
                SqlCeDataReader dr = cmd.ExecuteReader(System.Data.CommandBehavior.SingleRow);
                if (dr.Read())
                {
                    int i = 0;
                    if (dr["Modify"].ToString() == "U")
                    {
                        string s = ((Convert.ToInt32(dr["owshiddenversion"])) - 1).ToString();
                        cmd = new SqlCeCommand("UPDATE Sync_" + nameTable + " SET Modify = 'D', owshiddenversion = '" + s + "'" +
                          " where ID = '" + ID + "'; ", conn);
                        //выполняем команду этот оператор значит выполнить отличную от Select
                       i= cmd.ExecuteNonQuery();
                    }
                    else
                        if (dr["Modify"].ToString() == "I")
                        {
                            cmd = new SqlCeCommand("DELETE FROM  Sync_" + nameTable +
                          " where ID = '" + ID + "'; ", conn);
                            //выполняем команду этот оператор значит выполнить отличную от Select
                           i= cmd.ExecuteNonQuery();
                        }
                        else
                        {
                            cmd = new SqlCeCommand("UPDATE Sync_" + nameTable + " SET Modify = 'D' " +
                              " where ID IN ('" + ID + "') ", conn);
                            //выполняем команду этот оператор значит выполнить отличную от Select
                           i= cmd.ExecuteNonQuery();
                        }
                    if (i == 0)
                    {
                        Debug.Assert(false, "ShellFolderSync.cs RemoveCollaboratore() \n Bab delete ITEM \n");
                    }
                }
                else
                {
                    ID = "";
                }
                dr.Close();
                cmd.Dispose();
                cmd = null;
            }
            catch (Exception err)
            {
                Debug.Assert(false, "ShellFolderSync.cs RemoveCollaboratore()" + "\n" + err.Message + "\n -->" + err.Source + "\n"); 
            }
            finally
            {
                //закрываем подключение
                conn.Close();
                conn.Dispose();
                conn = null;
            }
        }
        #endregion
    }
}
